#include "Background.h"
#include "Charlie.h"

Background::Background(): 
Background(BG_PATH, true) {

}

Background::Background(bool horz): 
Background(BG_PATH, horz) {

}

Background::Background(const std::string &path): 
Background(path, true) {

}

Background::Background(const std::string &path, bool horz) :
isHorz(horz),
left(0),
right(0), 
mileage(0), 
leftMileage(0), 
rightMileage(0), 
leftMileageDisplay(0), 
rightMileageDisplay(0) {
	// claculate the meters from the start to the end
	end = MILEAGE_TO_FINISH + BG_WIDTH;
	end /= BG_WIDTH;
	end *= METERS_PER_TILE;
	
	// background
	left = new Sprite(path);
	right = new Sprite(path);

	// mileage display
	leftMileage = new Sprite(BG_MILEAGE_PATH, 0, 0, BG_MILEAGE_W, BG_MILEAGE_H);
	rightMileage = new Sprite(BG_MILEAGE_PATH, 0, 0, BG_MILEAGE_W, BG_MILEAGE_H);
	leftMileageDisplay = new SpriteText(BG_FONT_PATH, TTF_STYLE_NORMAL, DEFAULT_MILEAGE_DISPLAY, BG_FONT_SIZE, 0, 0);
	rightMileageDisplay = new SpriteText(BG_FONT_PATH, TTF_STYLE_NORMAL, DEFAULT_MILEAGE_DISPLAY, BG_FONT_SIZE, 0, 0);

	// position the sprites properly
	ResetPos();

	// display the right numbers
	DisplayMilage();
}

void Background::ResetPos() {
	// position the left sprite at the starting position
	SDL_Rect r;
	r.x = BG_START_X;
	r.y = BG_START_Y;
	r.w = BG_WIDTH;
	r.h = BG_HEIGHT;
	left->SetDstRect(r);

	// set the right frame one full screen away
	if (isHorz) {
		r.x += BG_WIDTH;
		right->SetDstRect(r);
	} else {
		r.y += BG_HEIGHT;
		right->SetDstRect(r);
	}

	return;
}

void Background::ScrollBy(int u) {
	// keep track of the total milage
	mileage += u;
	
	// determine the position of the left sprite
	int pos;
	if (isHorz) {
		pos = mileage % BG_WIDTH;
		// since we are scrolling to the left, the position of the left sprite will be negative by the amount to scroll
		pos *= -1;
		if (pos > 0) {
			// if the position is positive, however, it would leave a blank space
			// because there is nothing to the left of the left sprite
			// as such, the right sprite will have to be placed there, and the left sprite will have to be taken back a whole screen
			pos -= BG_WIDTH;
		}
	} else {
		pos = mileage % BG_HEIGHT;
		// since we are scrolling to the top, the position of the left sprite will be negative by the amount to scroll
		pos *= -1;
		if (pos > 0) {
			// if the position is positive, however, it would leave a blank space
			// because there is nothing to the top of the left sprite
			// as such, the right sprite will have to be placed there, and the left sprite will have to be taken back a whole screen
			pos -= BG_HEIGHT;
		}
	}
	

	if (isHorz) {
		left->SetPosition(pos, BG_START_Y);
		right->SetPosition(left->GetRect().x + BG_WIDTH, left->GetRect().y);
	} else {
		left->SetPosition(BG_START_X, pos);
		right->SetPosition(left->GetRect().x, left->GetRect().y + BG_HEIGHT);
	}

	// display the right numbers
	DisplayMilage();

	return;
}

void Background::Reset() {
	mileage = 0;
	ResetPos();
	
	return;
}

void Background::DisplayMilage() {
	// special treatment for negative mileage
	int tmpMileage = mileage;
	if (tmpMileage < 0) {
		tmpMileage -= BG_WIDTH;
	}

	// calculate which tile the player is in and conver tthis into meters
	int meters = tmpMileage / BG_WIDTH * METERS_PER_TILE;

	// convert to string and fill the numbers with 0s
	std::stringstream ssl, ssh;
	ssl << std::setfill(MILEAGE_TEXT_FILLER) << std::setw(MILEAGE_TEXT_WIDTH) << (end - meters);
	ssh << std::setfill(MILEAGE_TEXT_FILLER) << std::setw(MILEAGE_TEXT_WIDTH) << (end - (meters + METERS_PER_TILE));

	leftMileageDisplay->SetMessage(ssl.str());
	rightMileageDisplay->SetMessage(ssh.str());

	// reposition the mileage background and text
	leftMileage->SetPosition(left->GetRect().x + BG_MILEAGE_OFFSET_X, left->GetRect().y + BG_MILEAGE_OFFSET_Y);
	rightMileage->SetPosition(right->GetRect().x + BG_MILEAGE_OFFSET_X, right->GetRect().y + BG_MILEAGE_OFFSET_Y);
	leftMileageDisplay->SetPosition(leftMileage->GetRect().x + BG_MILEAGE_TEXT_OFFSET_X, leftMileage->GetRect().y + BG_MILEAGE_TEXT_OFFSET_Y);
	rightMileageDisplay->SetPosition(rightMileage->GetRect().x + BG_MILEAGE_TEXT_OFFSET_X, rightMileage->GetRect().y + BG_MILEAGE_TEXT_OFFSET_Y);

	return;
}

Background::~Background() {
	// do not delete the sprites, as they are components and will be deleted by the engine
}
